#include <stdio.h>
#include "mysql.h"

bool connect_mysql1(MYSQL *mysql)
{
    if (mysql_init(mysql) == NULL)
    {
        printf("初始化数据库失败\n");
        return false;
    }
    if (!mysql_real_connect(mysql, "localhost", "lizhibiao", "lizhibiao990410", "ftp", 3306, NULL, 0))
    {
        printf("连接数据库失败\n");
        return false;
    }
    return true;
}

// 登陆数据库
bool connect_mysql(MYSQL *mysql, const char *account, const char *password, const char *dbname)
{
    if (account == NULL || password == NULL || dbname == NULL)
    {
        printf("请指定mysql用户、密码、数据库名\n");
        return false;
    }
    if (mysql_init(mysql) == NULL)
    {
        printf("初始化数据库失败\n");
        return false;
    }
    // if(!mysql_real_connect(mysql,"192.168.208.130",account, password, dbname, 3306, NULL, 0))
    if (!mysql_real_connect(mysql, "localhost", "lizhibiao", "lizhibiao990410", "test", 3306, NULL, 0))
    {
        printf("连接数据库失败\n");
        perror("mesql_");
        return false;
    }
    return true;
}

// 用户登陆
bool login(MYSQL *mysql)
{
    // 利用calloc创建账号空间和密码空间
    char *user = (char *)calloc(100, sizeof(char));
    char *password = (char *)calloc(100, sizeof(char));
    if (user == NULL || password == NULL)
    {
        perror("calloc()");
        exit(-1);
    }

    // 从键盘上输入账号和密码
    printf("请输入ftp账号\n");
    if (!f_gets(user, 100))
    {
        printf("账号输入失败\n");
        return false;
    }
    printf("请输入账号的密码\n");
    if (!f_gets(password, 100))
    {
        printf("密码输入失败\n");
        return false;
    }

    // 密码对比
    // 创建一个加密密码
    unsigned char *cipher = str_to_sha256(password);

    // 利用SHA512 加密
    // 这样我们就得到了这个密码经过加密之后的结果，之后就将它与数据库中的密码数据做对比
    // SHA512(password, strlen(password), cipher);
    MYSQL_RES *result;
    MYSQL_ROW row;

    //     select t.name, p.cipher_code
    // from pass_word p,
    // (select u.id id,u.name from user u where name = 'xx') t
    // where t.id = p.user_id;
    bool flag;

    char sql[256];
    memset(sql, 0, sizeof(sql));
    char *t1 = "select t.name, p.cipher_code from pass_word p,\
(select u.id id,u.name from user u where name = ";
    char *t2 = ") t where t.id = p.user_id";
    sprintf(sql, "%s%c%s%c%s", t1, '"', user, '"', t2);

    if (mysql_real_query(mysql, sql, strlen(sql)))
    {
        printf("查询失败\n");
        return false;
    }
    else
    {
        // printf("ok\n");

        result = mysql_store_result(mysql);
        row = mysql_fetch_row(result);
        if(row == NULL)
        {
            printf("用户不存在\n");
        }
        else
        {
            if (strcmp(cipher, row[1]) == 0)
            {
                printf("%s 欢迎登陆\n", row[0]);
                flag = true;
            }
            else
            {
                printf("您输入的密码错误\n");
                flag = false;
            }
            printf("---------------------------------------\n");
            mysql_free_result(result);
        }
    }
    free(user);
    free(password);
    // free(cipher);
    return flag;
}

// 创建一个用户
bool create_user(MYSQL *mysql)
{
    MYSQL_RES *result;
    MYSQL_ROW row;
    char *user = (char *)calloc(100, sizeof(char));
    char *password = (char *)calloc(100, sizeof(char));
    bool ret = true;
    if (user == NULL || password == NULL)
    {
        perror("calloc()");
        exit(-1);
    }
    printf("请输入您想创建的ftp账号\n");
    if (!f_gets(user, 100))
    {
        printf("账号输入失败\n");
        return false;
    }

    char sql[256];
    memset(sql, 0, sizeof(sql));
    char *t1 = "insert into user(name) values(";
    sprintf(sql, "%s%c%s%c%c", t1, '"', user, '"', ')');

    if (mysql_query(mysql, sql))
    {
        printf("用户创建失败\n");
        printf("您输入的用户名已经存在\n");
        return false;
    }
    else
    {
        // 查询刚才创建的用户的id
        memset(sql, 0, sizeof(sql));
        t1 = "select u.id from user u where u.name = ";
        sprintf(sql, "%s%c%s%c", t1, '"', user, '"');
        mysql_real_query(mysql, sql, strlen(sql));
        result = mysql_store_result(mysql);
        row = mysql_fetch_row(result);
        int u_id = atoi(row[0]);
        mysql_free_result(result);
        // 向数据库中插入对应的密码
        printf("请输入您的密码\n");
        if (!f_gets(password, 100))
        {
            printf("密码输入失败\n");
            return false;
        }
        // 确认密码
        char *temp = (char *)calloc(100, sizeof(char));
        bool p_flag = true; // 用于密码输入成功判断
        while (p_flag)
        {
            memset(temp, 0, 100);
            printf("请再次输入您的密码\n");
            if (!f_gets(temp, 100))
            {
                printf("确认密码输入失败\n");
                return false;
            }

            // 对前后两次输入的密码进行比对
            if (!strcmp(password, temp) == 0)
            {
                printf("对不起，您前后两次输入的密码不一致\n");
                printf("您可以选择重新输入\n");
            }
            else
            {
                p_flag = false;
            }
        }
        free(temp);
        temp = NULL;
        // 将密码加密
        char *cipher = str_to_sha256(password);

        memset(sql, 0, sizeof(sql));
        t1 = "insert into pass_word(cipher_code, user_id) values(";
        sprintf(sql, "%s%c%s%c%c%d%c", t1, '"', cipher, '"', ',', u_id, ')');
        // printf("sql = %s\n", sql);
        if (mysql_query(mysql, sql))
        {
            printf("密码插入失败\n");
            ret = false;
        }
        else
        {
            printf("用户：%s 创建成功\n", user);
        }
        // free(cipher);
        cipher = NULL;
    }
    free(user);
    free(password);
    return ret;
}

// 关闭数据库
bool close_mysql(MYSQL *mysql)
{
    if (mysql != NULL)
    {
        mysql_close(mysql);
        // mysql = NULL;
    }
}

char *f_gets(char *str, int size)
{
    if (str == NULL || size <= 0)
    {
        printf("str 为空 或 大小为0\n");
        return NULL;
    }
    char *temp = fgets(str, size, stdin);
    if (temp == NULL)
    {
        return NULL;
    }
    else
    {
        char *find = strchr(str, '\n');
        if (find)
            *find = '\0';
        else
        {
            while (getchar() != '\n')
                continue;
        }
    }
    return str;
}

char *str_to_sha256(const unsigned char *d)
{
    unsigned char *result = (char *)calloc(SHA256_DIGEST_LENGTH, sizeof(char));

    SHA256(d, strlen(d), result);

    char *temp = (char *)calloc(150, sizeof(char));
    char xx[5];

    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        memset(&xx, 0, sizeof(xx));
        sprintf(xx, "%X", result[i]);
        strcat(temp, xx);
    }
    free(result);
    return temp;
}

bool mysql_module(void)
{
    bool ret = true;
    MYSQL mysql;

    // char *account = (char *)calloc(100, sizeof(char));
    // char *password = (char *)calloc(100, sizeof(char));
    // char *dbname = (char *)calloc(50, sizeof(char));
    // printf("请输入数据库用户账号:\n");
    // f_gets(account, 100);
    // printf("请输入数据库用户账号的密码:\n");
    // f_gets(password, 100);
    // printf("请输入您想要使用的数据库名：\n");
    // f_gets(dbname, 100);
    // printf("accout = %s\n",account);
    // printf("password = %s\n",password);
    // printf("dbname = %s\n",dbname);
    // if(!connect_mysql(&mysql, account, password, dbname))
    // {
    //     printf("连接数据库失败\n");
    //     exit(-1);
    // }

    char ch;
    char option;
    char mysql_option[10];
    connect_mysql1(&mysql);
    while (1)
    {
        printf("--------------------------------------------------------\n");
        printf("**************** 欢迎使用 ftp 服务器系统 *****************\n");
        printf("********* 您是否已经拥有ftp 服务器的账号??? ***************\n");
        printf("***************** 1) 有          0) 没有 ****************\n");
        printf("--------------------------------------------------------\n");
        int flag;
        scanf("%d", &flag);
        // fflush(stdin);
        getchar();
        if (flag == 1)
        {
            // 调用登陆函数
            if (!login(&mysql))
            {
                printf("\n");
                printf("************** 您可以选择重新登陆或退出 *******************\n");
                printf("********* back) 重新登陆            quit) 退出 ***********\n");
                // option = getchar();
                // fflush(stdin);
                memset(mysql_option, 0, sizeof(mysql_option));
                f_gets(mysql_option, 10);
                if (strcmp(mysql_option, "quit") == 0)
                {
                    ret = false;
                    break;
                }
                else if(strcmp(mysql_option, "back") == 0)
                    continue;
                else
                {
                    ret = false;
                    printf("您输入的选项错误\n");
                }
            }
            // 记得break;
            break;
        }
        else if (flag == 0)
        {
            // create_user(&mysql);
            // 询问用户是否想要创建一个用户
            printf("\n");
            printf("**************** 您是否想要创建一个用户 *******************\n");
            printf("********** create) 创建             quit) 退出 ***********\n");
            memset(mysql_option, 0, sizeof(mysql_option));
            f_gets(mysql_option, 10);
            if (strcmp(mysql_option, "quit") == 0)
            {
                ret = false;
                break;
            }
            else if(strcmp(mysql_option, "create") == 0)
            {
                // char create_option;
                while (1)
                {
                    if (!create_user(&mysql))
                    {
                        printf("*********** 您可以选择重新创建或退出 ************\n");
                        printf("***** back) 重新创建             0)退出  *******\n");
                        memset(mysql_option, 0, sizeof(mysql_option));
                        f_gets(mysql_option, 10);
                        if (strcmp(mysql_option, "quit") == 0)
                        {
                            ret = false;
                            break;
                        }
                        else if(strcmp(mysql_option,"back") == 0)
                            continue;
                        else
                        {
                            ret = false;
                            printf("您输入的选项错误\n");
                            break;
                        }
                        
                    }
                    else
                        break;
                }
            }
            else
            {
                ret = false;
                printf("您输入的选项错误\n");
            }
            // 记得break;
            break;
        }
        else
        {
            printf("\n");
            printf("********** 您的输入选项有误，请选择退出或重新输入 **********\n");
            printf("************ 1) 重新选择             0) 退出 *************\n");
            option = getchar();
            getchar();
            if (option == '0')
            {
                ret = false;
                break;
            }
        }
    }
    return ret;
}